<?php


namespace App\Service\Store;

use App\Constants\Express;
use App\Dao\LogisticDao;
use App\Dao\OrderDao;
use App\Job\OrderConfirmJob;
use App\Kernel\Express\KdBird;
use App\Service\Service;
use Hyperf\Di\Annotation\Inject;

/**
 *
 * 快递服务
 * @author 陈奕文
 * @package App\Service\Store
 */
class ExpressService extends Service
{

    /**
     * 快递鸟
     * @Inject()
     * @var KdBird
     */
    private $kd_bird;

    /**
     * 订单Dao
     * @Inject()
     * @var OrderDao
     */
    private $order_dao;

    /**
     * 物流Dao
     * @Inject()
     * @var LogisticDao
     */
    private $logistics_dao;

    /**
     * 物流追踪
     * @param array $datas
     * @return array
     */
    public function trackPush(array $datas)
    {
        $numbers = []; // 成功订单号
        foreach ($datas as $data) {
            $logistic = $this->logistics_dao->find([
                ['number' => $data['LogisticCode']],
            ]);
            if (!$logistic ){
                return $this->kd_bird->show(false, "物流单号：".$data['LogisticCode'].";我们没有保存物流信息");
            }
            // 物流判断, 然后重新订阅
            if (!$data['Success'] &&
                (strpos($data['Reason'], '三天无轨迹') !== false ||
                    strpos($data['Reason'], '七天内无轨迹变化') !== false ) ) {
                $logistic->is_subscribe = 0; // 更改为未订阅
                $logistic->push_reason = $data['Reason']; // 最新推送返回的理由
                $logistic->save();

                $send['ShipperCode'] = $logistic->company_abbr; // 快递公司编码
                $send['LogisticCode'] = $logistic->number; // 快递单号
                $send['PayType'] = $logistic->pay_type; // 运费支付方式 1-现付，2-到付，3-月结 4-第三方付(仅 SF、KYSY支持)
                $send['CustomerName'] = $logistic->custom_name; // 客户名称
                // 收件人信息
                $send['Receiver']['Name'] = $logistic->name; // 收件人姓名
                $send['Receiver']['Mobile'] = $logistic->phone; // 收件人电话
                $send['Receiver']['ProvinceName'] = $logistic->province; // 收件人省
                $send['Receiver']['CityName'] = $logistic->city; // 收件人市
                $send['Receiver']['ExpAreaName'] = $logistic->district; // 收件人区
                $send['Receiver']['Address'] = $logistic->address; // 收件人地址
                $send['Receiver']['PostCode'] = $logistic->zip_code; // 收件人邮政编码

                // 发件人信息
                $send['Sender']['Name'] = $logistic->sender_name;
                $send['Sender']['Mobile'] = $logistic->sender_phone;
                $send['Sender']['ProvinceName'] = $logistic->sender_province;
                $send['Sender']['CityName'] = $logistic->sender_city;
                $send['Sender']['ExpAreaName'] = $logistic->sender_district;
                $send['Sender']['Address'] = $logistic->sender_addr;
                $send['Sender']['PostCode'] = $logistic->sender_zip_code;

                $resp = $this->kd_bird->orderTracesSubByJson($send, Express::BIRD_SUBSCRIBE); // 重新订阅

                if (!$resp["Success"]) { // 订阅失败
                    $this->logger('express')->error("订阅失败".json_encode($send));
                    $logistic->subscribe_reason = $resp['Reason']??"物流已多天无轨迹，自动重申订阅后，重新订阅失败".date("Y-m-d H:i:s"); // 订阅返回原因
                    $logistic->save();
                    return $this->kd_bird->show(false, json_encode($resp));
                } else {
                    $logistic->is_subscribe = 1; // 订阅成功
                    $logistic->subscribe_reason = $resp['Reason']??"物流已多天无轨迹，自动重申订阅后，重新订阅成功".date("Y-m-d H:i:s"); // 订阅返回原因
                    $logistic->save();
                    return $this->kd_bird->show(true);
                }

            }
            // 物流动态和状态更新
            $logistic->status = $data['State']; // 货物状态
            isset($data['Traces']) && $logistic->current_detail = $data['Traces']; // 当前物流情况
            $logistic->push_reason = $data['Reason']??"无。时间：".date("Y-m-d H:i:s"); // 推送理由
            $save = $logistic->save();
            if (!$save) {
                $this->logger('express')->error("物流信息保存失败：".json_encode($data));
                return $this->kd_bird->show(false,"物流单号：".$data['LogisticCode'].";物流信息保存失败");
            }
            // 订单检查是否存在
            $order = $this->order_dao->getFirstOrderByNo($logistic->order_no);
            if (!$order){
                $this->logger('express')->error("没有关联到订单:".json_encode($data));
                return $this->kd_bird->show(false,"物流单号：".$data['LogisticCode'].";没有关联到订单");
            }

            // 订单状态更新  待支付和已支付的状态时，判断要处理一下订单的状态更改，小于2的这两个状态需要在 已揽收=1，2-在途中选择一个，不选 4-问题件
            if ($order->status < 2 && ($data['State'] == 1 || $data['State'] == 2 )) { // 订单更新状态
                $order->status = 2; // 改变成发货状态
                $order->ship_time = time(); // 发货时间
                $order_save = $order->save();
                if (!$order_save) {
                    $this->logger('express')->error("订单保存失败:".json_encode($data));
                    return $this->kd_bird->show(false, "物流单号".$data['LogisticCode']."改变发货时间失败");
                }
            }
            // 物流状态为3的签收状态,且订单为发货状态
            if ($data['State'] == 3 ) { // 签收状态就1次
                $order->complete_time = time(); // 收货时间
                if (!$order->save())  {
                    $this->logger('express')->error("订单编号为：{$logistic->order_no}的订单收货时间更新失败");
                }
                $this->driver->push(new OrderConfirmJob($logistic->order_no), 60*60*24*10); // 10天后开始处理
            }

            $numbers[] = $data['LogisticCode']; // 收集成功的订单号
        }

        $json_numbers = json_encode($numbers);

        return $this->kd_bird->show(true, "物流单号：{$json_numbers} 保存都成功了");
    }

    /**
     * 物流追踪（增值版）
     * @param array $datas
     * @return mixed
     */
    public function trackPushAdd(array $datas)
    {
        $numbers = []; // 成功订单号
        foreach ($datas as $data) {
            $logistic = $this->logistics_dao->find([
                ['number' => $data['LogisticCode']],
            ]);
            if (!$logistic ){
                return $this->kd_bird->show(false, "物流单号：".$data['LogisticCode'].";我们没有保存物流信息");
            }
            // 物流判断, 然后重新订阅
            if (!$data['Success'] &&
                (strpos($data['Reason'], '三天无轨迹') !== false ||
                    strpos($data['Reason'], '七天内无轨迹变化') !== false ) ) {
                $logistic->is_subscribe = 0; // 更改为未订阅
                $logistic->push_reason = $data['Reason']; // 最新推送返回的理由
                $logistic->save();

                $send['ShipperCode'] = $logistic->company_abbr; // 快递公司编码
                $send['LogisticCode'] = $logistic->number; // 快递单号
                $send['PayType'] = $logistic->pay_type; // 运费支付方式 1-现付，2-到付，3-月结 4-第三方付(仅 SF、KYSY支持)
                $send['CustomerName'] = $logistic->custom_name; // 客户名称
                // 收件人信息
                $send['Receiver']['Name'] = $logistic->name; // 收件人姓名
                $send['Receiver']['Mobile'] = $logistic->phone; // 收件人电话
                $send['Receiver']['ProvinceName'] = $logistic->province; // 收件人省
                $send['Receiver']['CityName'] = $logistic->city; // 收件人市
                $send['Receiver']['ExpAreaName'] = $logistic->district; // 收件人区
                $send['Receiver']['Address'] = $logistic->address; // 收件人地址
                $send['Receiver']['PostCode'] = $logistic->zip_code; // 收件人邮政编码

                // 发件人信息
                $send['Sender']['Name'] = $logistic->sender_name;
                $send['Sender']['Mobile'] = $logistic->sender_phone;
                $send['Sender']['ProvinceName'] = $logistic->sender_province;
                $send['Sender']['CityName'] = $logistic->sender_city;
                $send['Sender']['ExpAreaName'] = $logistic->sender_district;
                $send['Sender']['Address'] = $logistic->sender_addr;
                $send['Sender']['PostCode'] = $logistic->sender_zip_code;

                $resp = $this->kd_bird->orderTracesSubByJson($send, Express::BIRD_SUBSCRIBE_ADD_VERSION); // 重新订阅（增值版）

                if (!$resp["Success"]) { // 订阅失败
                    $this->logger('express')->error("订阅失败".json_encode($send));
                    $logistic->subscribe_reason = $resp['Reason']??"物流已多天无轨迹，自动重申订阅后，重新订阅失败".date("Y-m-d H:i:s"); // 订阅返回原因
                    $logistic->save();
                    return $this->kd_bird->show(false, json_encode($resp));
                } else {
                    $logistic->is_subscribe = 1; // 订阅成功
                    $logistic->subscribe_reason = $resp['Reason']??"物流已多天无轨迹，自动重申订阅后，重新订阅成功".date("Y-m-d H:i:s"); // 订阅返回原因
                    $logistic->save();
                    return $this->kd_bird->show(true);
                }

            }
            // 物流动态和状态更新
            $logistic->status = $data['State']; // 货物状态
            isset($data['Traces']) && $logistic->current_detail = $data['Traces']; // 当前物流情况
            $logistic->push_reason = $data['Reason']??"无。时间：".date("Y-m-d H:i:s"); // 推送理由
            $logistic->status_ex = $data['StateEx']; // 货物状态（增值版）
            $save = $logistic->save();
            if (!$save) {
                $this->logger('express')->error("（增值版）物流信息保存失败：".json_encode($data));
                return $this->kd_bird->show(false,"（增值版）物流单号：".$data['LogisticCode'].";物流信息保存失败");
            }
            // 订单检查是否存在
            $order = $this->order_dao->getFirstOrderByNo($logistic->order_no);
            if (!$order){
                $this->logger('express')->error("（增值版）没有关联到订单:".json_encode($data));
                return $this->kd_bird->show(false,"（增值版）物流单号：".$data['LogisticCode'].";没有关联到订单");
            }

            // 订单状态更新  待支付和已支付的状态时，判断要处理一下订单的状态更改，小于2的这两个状态需要在 已揽收=1，2-在途中选择一个，不选 4-问题件
            if ($order->status < 2 && ($data['State'] == 1 || $data['State'] == 2 )) { // 订单更新状态
                $order->status = 2; // 改变成发货状态
                $order->ship_time = time(); // 发货时间
                $order_save = $order->save();
                if (!$order_save) {
                    $this->logger('express')->error("（增值版）订单保存失败:".json_encode($data));
                    return $this->kd_bird->show(false, "（增值版）物流单号".$data['LogisticCode']."改变发货时间失败");
                }
            }
            // 物流状态为3的签收状态,且订单为发货状态
            if ($data['State'] == 3 ) { // 签收状态就1次
                $order->complete_time = time(); // 收货时间
                if (!$order->save())  {
                    $this->logger('express')->error("（增值版）订单编号为：{$logistic->order_no}的订单收货时间更新失败");
                }
                $this->driver->push(new OrderConfirmJob($logistic->order_no), 60*60*24*10); // 10天后开始处理
            }

            $numbers[] = $data['LogisticCode']; // 收集成功的订单号
        }

        $json_numbers = json_encode($numbers);

        return $this->kd_bird->show(true, "（增值版）物流单号：{$json_numbers} 保存都成功了");
    }

}